#pragma once

#include "ephcom.h"
#include "SimpleFile.h"
#include "GetEphemInterface.h"

class CBufferHolder
{
	typedef struct{
		int Offset;
		vector<double> vec;
		bool last;
	} Buffer;
public:
	typedef auto_ptr<CBufferHolder> AP;

	CBufferHolder(FILE * file, int nBufSize);
	double *GetBufferAtOffset(int nOffset);
protected:
	FILE	*m_File;
	Buffer	m_buffer[2];
};



class CEphemDE: public IGetCoord
{
public:
	CEphemDE (LPCTSTR stzEphemFileName);
	virtual ~CEphemDE (void);

	bool GetCoord(double date, bool bBaryCenter, AllBodies & coords, bool bGetVelocity);
protected:
	double GetParam(LPCSTR szName);

	/*	Read a JPL Ephemeris header in binary format.  Store values in
	an ephcom_Header struct. */
	int ephcom_readbinary_header();

	/* ephcom_get_coords() - Interpolate positions and velocities at given time.*/
	int ephcom_get_coords(	struct ephcom_Coords *coords, bool bGetVelocity); 

	/* Planetary Ephemeris.  Takes coordinates already calculated in
	coords structure an converts to vectors and vector dot in testr[].
	Bodies start at 1 for Mercury, to match the JPL PLEPH() numbering.
	Values for ntarg and ncntr correspond to locations ntarg-1 and
	ncntr-1 in coords->pv[]. */
	int ephcom_pleph(struct ephcom_Coords *coords, int ntarg, int ncntr, double *r);

	/* ephcom_cheby() - interpolate at a point using Chebyshev coefficients */
	int ephcom_cheby(
		double x,      /* Value of x over [-1,1] for Chebyshev interpolation */
		double span,   /* Span in time of subinterval, for velocity */
		double *y,     /* Chebyshev coefficients */
		int ncoords,   /* Total number of coordinates to interpolate */
		int ncoeffs,   /* Number of Chebyshev coefficients per coordinate */
		double *pv,    /* Array to hold position in 1st half, velocity in 2nd */
		bool bGetVelocity) ;
protected:
	double * GetPosBuffer(double dTime);
	double * GetVelBuffer(double dTime);
protected:
	ephcom_Header			m_header;
	CSimpleFile				m_file;
	double					m_dGM[BODY_COUNT];

	CBufferHolder::AP		m_ReadBlockBuff;

	vector<double>			m_vecPos;
	vector<double>			m_vecVel;
	double					m_lastx; /* x from last call; initialize to impossible value */
	double					m_lastxv; /* x from last call; initialize to impossible value */
};

